/**
 *\file liste.c
 *\author Raphaël Diana
 *\author Imad Smaani
 */
#include "liste.h"

Liste * initListe()
{
    Liste * l;
    l=malloc(sizeof(Liste));
    assert(l!=NULL);
    l->ad=NULL;
    return l;
}


void testamentListe(Liste **l)
{
    Cellule * tmp;
    assert((*l)!=NULL);
    tmp=(*l)->ad;

    while((*l)->ad != NULL)
    {
        tmp=(*l)->ad;
        (*l)->ad=tmp->suivant;
        free(tmp);
    }
    free(*l);
    (*l)=NULL;
}



void insertElement(Liste *l, Carte * valeur_inseree)
{
    Cellule * tmp;
    Cellule * nouveau;
    assert(l!=NULL);

    nouveau=malloc(sizeof(Cellule));
    nouveau->suivant=NULL;
    nouveau->info=valeur_inseree;
    tmp=l->ad;

    if (tmp != NULL)
    {
        while(tmp->suivant != NULL)
        {
            tmp=tmp->suivant;
        }
        tmp->suivant=nouveau;
    }
    else
    {
        l->ad=nouveau;
    }
}



void supprElement(Liste * l)
{
    Cellule * tmp;
    tmp=l->ad;
    assert(l!=NULL);

    if( tmp!=NULL && tmp->suivant==NULL)
    {
        free(l->ad);
        l->ad=NULL;
    }
    else
    {
        while(tmp->suivant->suivant != NULL)
        {
            tmp=tmp->suivant;
        }
        free(tmp->suivant);
        tmp->suivant=NULL;
    }
}



Carte * retireEnTete(Liste *l)
{
    Carte * res;
    Cellule * tmp;
    res=l->ad->info;
    tmp=l->ad;
    l->ad=tmp->suivant;
    res=tmp->info;
    free(tmp);

    return res;
}



Cellule * iemeCellule (const Liste *l,int indElement)
{
    int j;
    Cellule * tmp;
    assert(l!=NULL);
    if(l->ad==NULL)
    {
        return NULL;
    }
    else
    {
        tmp=l->ad;
        for(j=1; j<indElement; j++)
        {
            if(tmp->suivant!=NULL)
            {
                tmp=tmp->suivant;
            }
            else
            {
                return NULL;
            }
        }
        return tmp;
    }
}


Carte *getInfo(const Liste *l,int indElement)
{
    if(iemeCellule(l,indElement)!=NULL)
    {
        return iemeCellule(l,indElement)->info;
    }
    else
    {
        return NULL;
    }
}



unsigned int getNombreElement(const Liste* liste)
{
    unsigned int i=0;
    Cellule* maCellule;
    if(liste==NULL || liste->ad==NULL)
    {
        return 0;
    }
    else
    {
        maCellule=liste->ad;
        while(maCellule!=NULL)
        {
            maCellule=maCellule->suivant;
            i++;
        }
        return i;
    }
}


void afficheListe(const Liste * l)
{
    Cellule * tmp;
    assert(l!=NULL);
    tmp=l->ad;
    while(tmp != NULL)
    {
        afficherCarte(tmp->info);
        printf("\n");
        tmp=tmp->suivant;
    }
}
/*------------------Utilisation de la structure liste pour les mains---------------------------*/


int testSeparerListe(const Liste* hand)
{
    return getNombreElement(hand)==2 && getFaceCarte(getInfo(hand,1))==getFaceCarte(getInfo(hand,2));
}

Liste * separeListe(Liste* hand)
{
    Liste* hand2=initListe();

    assert(hand!=NULL);
    assert(testSeparerListe(hand));

    insertElement(hand2, getInfo(hand,2));
    supprElement(hand);
    return hand2;
}

unsigned int testNombreCarte(const Liste* hand)
{
    return getNombreElement(hand);
}

unsigned int valeurMain(const Liste* hand)
{
    unsigned int i, as;
    unsigned int valeur;

    assert(hand!=NULL);

    valeur=0;
    as=0;

    for(i=0; i<getNombreElement(hand); i++)
    {
        if(getValeurCarte(getInfo(hand, i+1))==11) /*cas de l'as*/
        {
            as++;
            valeur=valeur+11;
        }
        else
        {
            valeur=valeur+getValeurCarte(getInfo(hand, i+1));
        }
        while (valeur>21 && as!=0)/*cas du depacement*/
        {
            valeur=valeur-10;/*changement de la valeur de l'as a 1*/
            as--;
        }
    }
    return valeur;
}

unsigned int getValeurMain(const Liste * hand)
{
    assert (hand!=NULL);
    return valeurMain(hand);
}

int testBlackjack(const Liste* hand)
{
    assert(hand!=NULL);
    return (getNombreElement(hand)==2 && valeurMain(hand)==21);
}

int testSaute(const Liste* hand)
{
    valeurMain(hand);
    return valeurMain(hand)>21 ;
}

void afficheMain(const Liste * hand)
{
    assert(hand!=NULL);

    if(getNombreElement(hand)==0)
    {
        printf("Main vide\n");
    }
    else
    {
        afficheListe(hand);
    }
}
